﻿using System;
using System.Threading.Tasks;
using Loong.Domain.Uow;

namespace Loong.BackgroundJobs
{
    public class BackgroundJobStore : IBackgroundJobStore
    {
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IBackgroundJobDbAccessor _backgroundJobDbAccessor;

        public BackgroundJobStore(
            IUnitOfWorkManager unitOfWorkManager,
            IBackgroundJobDbAccessor backgroundJobDbAccessor)
        {
            _unitOfWorkManager = unitOfWorkManager;
            _backgroundJobDbAccessor = backgroundJobDbAccessor;
        }

        public async Task<BackgroundJobInfo> GetAndLockWaitingJobAsync()
        {
            using (var uow = _unitOfWorkManager.Begin())
            {
                var waitingJob = await _backgroundJobDbAccessor.GetWaitingJobAsync();

                if (waitingJob != null)
                {
                    waitingJob.LockEndTime = DateTime.Now.AddMinutes(30);
                    await _backgroundJobDbAccessor.LockJobAsync(waitingJob);
                }

                await uow.CompleteAsync();

                return waitingJob;
            }
        }

        public async Task InsertJobAsync(BackgroundJobInfo jobInfo)
        {
            await _backgroundJobDbAccessor.InsertAsync(jobInfo);
        }

        public async Task UpdateJobAsync(BackgroundJobInfo jobInfo)
        {
            using (var uow = _unitOfWorkManager.Begin())
            {
                await _backgroundJobDbAccessor.UpdateAsync(jobInfo);

                await uow.CompleteAsync();
            }
        }

        public async Task DeleteJobAsync(long jobId)
        {
            await _backgroundJobDbAccessor.DeleteAsync(j => j.Id == jobId);
        }

        public async Task DeleteJobAsync(BackgroundJobInfo jobInfo)
        {
            using (var uow = _unitOfWorkManager.Begin())
            {
                await _backgroundJobDbAccessor.DeleteAsync(jobInfo);

                await uow.CompleteAsync();
            }
        }
    }
}
